﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;

public class ZipUtil
{
	public static byte[] compressString(string str)
	{
		return compress(Encoding.UTF8.GetBytes(str));
	}

	public static string decompressString(byte[] data)
	{
		byte[] bytes = decompress(data);
		return Encoding.UTF8.GetString(bytes);
	}

	public static byte[] compress(byte[] data)
	{
		try
		{
			MemoryStream memoryStream = new MemoryStream();
			DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress, leaveOpen: true);
			deflateStream.Write(data, 0, data.Length);
			deflateStream.Close();
			return memoryStream.ToArray();
		}
		catch (Exception ex)
		{
			throw new Exception(ex.Message);
		}
	}

	public static byte[] decompress(byte[] data)
	{
		try
		{
			MemoryStream ms = new MemoryStream(data);
			InflaterInputStream gz = new InflaterInputStream(ms);
			MemoryStream msreader = new MemoryStream();
			int count = 0;
			byte[] buffer = new byte[4096];
			while ((count = gz.Read(buffer, 0, buffer.Length)) != 0)
			{
				msreader.Write(buffer, 0, count);
			}
			gz.Close();
			ms.Close();
			msreader.Position = 0L;
			byte[] depress = msreader.ToArray();
			msreader.Close();
			return depress;
		}
		catch (Exception ex)
		{
			throw new Exception(ex.Message);
		}
	}

	public static void CompressDir(ZipOutputStream zipOutput, string source, string relativePath = "")
	{
		ZipEntry dirEntry = new ZipEntry(source.Replace("\\", "/").Substring(relativePath.Length) + "/");
		zipOutput.PutNextEntry(dirEntry);
		zipOutput.Flush();
		string[] fileSystemEntries = Directory.GetFileSystemEntries(source);
		foreach (string file in fileSystemEntries)
		{
			if (Directory.Exists(file))
			{
				CompressDir(zipOutput, file, relativePath);
			}
			else
			{
				CompressFile(zipOutput, file, relativePath);
			}
		}
	}

	public static void CompressFile(ZipOutputStream zipOutput, string file, string relativePath = "")
	{
		FileStream fs = File.OpenRead(file);
		byte[] buffer = new byte[4096];
		file = file.Replace("\\", "/");
		ZipEntry entry = new ZipEntry(file.Substring(relativePath.Length));
		entry.IsUnicodeText = true;
		entry.DateTime = DateTime.Now;
		zipOutput.PutNextEntry(entry);
		int sourceBytes;
		do
		{
			sourceBytes = fs.Read(buffer, 0, buffer.Length);
			zipOutput.Write(buffer, 0, sourceBytes);
		}
		while (sourceBytes > 0);
	}

	public static void CompressFileList(string path, List<string> fileNames, List<byte[]> fileDatas)
	{
		if (fileNames.Count == 0)
		{
			return;
		}
		ZipOutputStream s = new ZipOutputStream(File.Create(path));
		s.SetLevel(6);
		for (int i = 0; i < fileNames.Count; i++)
		{
			string name = fileNames[i];
			byte[] fileData = fileDatas[i];
			ZipEntry entry = new ZipEntry(name);
			entry.IsUnicodeText = true;
			entry.DateTime = DateTime.Now;
			s.PutNextEntry(entry);
			s.Write(fileData, 0, fileData.Length);
		}
		s.Finish();
		s.Close();
	}
}